package rm.ep.server;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import rm.ep.shared.LogEntity;
import rm.ep.shared.EnquiryEntity;
import rm.ep.shared.ProgressEntity;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;

public class EnquiryDAO extends BaseDAO {

	static {
		Properties properties = new Properties();
		InputStream is = null;
		try {
			is = ClassLoader.getSystemResourceAsStream("rm/ep/server/EnquiryDAO.properties");
		    properties.load(is);
		    is.close();
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		} 
		E_NEW_SUBJECT = properties.getProperty("enquiry.new.subject");
		E_NEW_BODY = properties.getProperty("enquiry.new.body");
		E_DEACTIVATED_SUBJECT = properties.getProperty("enquiry.deactivated.subject");
		E_DEACTIVATED_BODY = properties.getProperty("enquiry.deactivated.body");
		E_REACTIVATED_SUBJECT = properties.getProperty("enquiry.reactivated.subject");
		E_REACTIVATED_BODY = properties.getProperty("enquiry.reactivated.body");
		E_PURGE_SUBJECT = properties.getProperty("enquiry.purge.subject");
		E_PURGE_BODY = properties.getProperty("enquiry.purge.body");
		E_ACTIVITY_SUBJECT = properties.getProperty("enquiry.activity.subject");
		E_ACTIVITY_BODY = properties.getProperty("enquiry.activity.body");
		E_LONG_ACTIVITY_SUBJECT = properties.getProperty("enquiry.long.activity.subject");
		E_LONG_ACTIVITY_BODY = properties.getProperty("enquiry.long.activity.body");
	}
	
	public EnquiryEntity insert(String type, final String email, String detail) {
		final EnquiryEntity e = new EnquiryEntity(type, email, detail);
		ofy().put(e); // no logging -> could be bogus entries
		sendEmail(email, EMAIL_ADDRESS_NOREPLY, E_NEW_SUBJECT, E_NEW_BODY);
		return e;
	}
	
	public EnquiryEntity deActivate(Long id) {
		final EnquiryEntity e = ofy().get(EnquiryEntity.class, id);
		e.setActive(Boolean.FALSE);
		transact(new Transactable() {
			@Override
			public void execute(Objectify ofy) {
				com.google.appengine.api.datastore.Key key = Key.raw(ofy.put(e));
				ofy.put(new LogEntity(getOperator(e.getEmail()), "De-Activated", key));
			}
		});
		sendEmail(e.getEmail(), EMAIL_ADDRESS_NOREPLY, E_DEACTIVATED_SUBJECT, E_DEACTIVATED_BODY);
		notifyEnquiryUpdate(e);
		return e;
	}
	
	public EnquiryEntity reActivate(Long id) {
		final EnquiryEntity e = ofy().get(EnquiryEntity.class, id);
		e.setActive(Boolean.TRUE);
		transact(new Transactable() {
			@Override
			public void execute(Objectify ofy) {
				com.google.appengine.api.datastore.Key key = Key.raw(ofy.put(e));
				ofy.put(new LogEntity(getOperator(e.getEmail()), "Re-Activated", key));
			}
		});
		sendEmail(e.getEmail(), EMAIL_ADDRESS_NOREPLY, E_REACTIVATED_SUBJECT, E_REACTIVATED_BODY);
		notifyEnquiryUpdate(e);
		return e;
	}
	
	public List<EnquiryEntity> selectActive() {
		return ofy().query(EnquiryEntity.class).filter("fIsActive", Boolean.TRUE).list();
	}

	public List<EnquiryEntity> selectInActive() {
		return ofy().query(EnquiryEntity.class).filter("fIsActive", Boolean.FALSE).list();
	}

	public ProgressEntity addProgress(String staff, String addressees, String progress, 
			Long enquiryId, Long fileEntityId) {
		EnquiryEntity e = ofy().get(EnquiryEntity.class, enquiryId);
		Key<EnquiryEntity> eKey = ofy().getFactory().getKey(e);
		com.google.appengine.api.datastore.Key parent = Key.raw(eKey);
		final ProgressEntity p = new ProgressEntity(staff, addressees, progress, parent, fileEntityId);
		final LogEntity l = new LogEntity(staff, "Progress Added", parent);
		transact(new Transactable() {
			@Override
			public void execute(Objectify ofy) {
				ofy.put(p, l);
			}
		});
		notifyEnquiryUpdate(e);
		return p;
	}
	
	public void purgeNewEnquiries() {
		
		long week1 = System.currentTimeMillis() - 1000*60*60*24*7;
		long week2 = week1 * 2;
		
		List<EnquiryEntity> l = ofy().query(EnquiryEntity.class)
									 .filter("fIsActive", Boolean.FALSE)
									 .filter("fModifiedAt < ", week1)
									 .list();
		
		for (EnquiryEntity e : l) {
			int cnt = ofy().query(LogEntity.class).ancestor(e).count();
			if (cnt == 0) { // never activated !
				if (e.getLastModifiedTime() < week2) {
					// too long, has been informed already so delete
					ofy().delete(e);
				} else {
					// send warning
					sendEmail(e.getEmail(), EMAIL_ADDRESS_NOREPLY, E_PURGE_SUBJECT, E_PURGE_BODY);
				}
			}
		}
		
	}
	
	public void closeInActive() {
		
		long week1 = System.currentTimeMillis() - 1000*60*60*24*7;
		long week4 = week1 * 4, week5 = week1 * 5;
		
		List<EnquiryEntity> l = ofy().query(EnquiryEntity.class)
									 .filter("fIsActive", Boolean.TRUE)
									 .filter("fModifiedAt < ", week1)
									 .list();
		
		for (EnquiryEntity e : l) {
			if (e.getLastModifiedTime() < week5) {
				deActivate(e.getId());
			} else if (e.getLastModifiedTime() < week4) {
				// warning before closing
				String email = e.getType().toLowerCase() + "@trade.gov.mv";
				sendEmail(email, EMAIL_ADDRESS_NOREPLY, E_LONG_ACTIVITY_SUBJECT, E_LONG_ACTIVITY_BODY);
			} else {
				// send inactivity email
				String email = e.getType().toLowerCase() + "@trade.gov.mv";
				sendEmail(email, EMAIL_ADDRESS_NOREPLY, E_ACTIVITY_SUBJECT, E_ACTIVITY_BODY);
			}
		}
		
	}
	
	private void notifyEnquiryUpdate(EnquiryEntity e) {

		StringBuilder builder = new StringBuilder();
		builder.append("<p/>The following enquiry has been updated.<p/>")
		   .append("<br/><b>Created</b> : ").append(formatDate(e.getCreatedTime()))
		   .append("<br/><b>Type</b> : ").append(e.getType())
		   .append("<br/><b>Client</b> : ").append(e.getEmail())
		   .append("<br/><b>Enquiry</b> : ").append(e.getDetail())
		   .append("<br/><b>Last Update</b> : ").append(e.getDetail())
		   .append("<br/><b>Status</b> : ").append(e.isActive()?"OPEN":"CLOSED");
		List<ProgressEntity> l = getChildren(e, ProgressEntity.class);
		for (ProgressEntity p : l) {
		   builder
			   .append("<hr/><br/>&nbsp;<b>Date</b> : ").append(formatDate(p.getCreatedTime()))
			   .append("<br/>&nbsp;<b>Sender</b> : ").append(p.getStaff())
			   .append("<br/>&nbsp;<b>Detail</b> : ").append(p.getProgress())
			   .append("<br/>&nbsp;<b>Attachment</b> : ").append(p.getFileEntityId()== null?"NO":"YES");
		}
		builder.append("<hr/>");
		
		String email = e.getType().toLowerCase() + "@trade.gov.mv";
		String subj = e.getType() + " Enquiry by : " + e.getEmail();
		sendEmail(email, EMAIL_ADDRESS_NOREPLY, subj, builder.toString());
		
	}

	protected static String E_NEW_SUBJECT, E_NEW_BODY,
							E_DEACTIVATED_SUBJECT, E_DEACTIVATED_BODY,
							E_REACTIVATED_SUBJECT, E_REACTIVATED_BODY,
							E_PURGE_SUBJECT, E_PURGE_BODY,
							E_ACTIVITY_SUBJECT, E_ACTIVITY_BODY,
							E_LONG_ACTIVITY_SUBJECT, E_LONG_ACTIVITY_BODY;

}
